package com.papper.mng.controller.system;

import com.papper.common.annotation.PapperLog;
import com.papper.common.bean.sys.SysGroup;
import com.papper.common.bean.sys.SysSystem;
import com.papper.common.bean.sys.SysUser;
import com.papper.common.config.LocalConfig;
import com.papper.common.config.SysSystemHelp;
import com.papper.common.constant.SystemConstants;
import com.papper.common.service.sys.SysGroupService;
import com.papper.common.service.sys.SysSystemService;
import com.papper.common.service.sys.SysUserService;
import com.papper.common.utils.encrypt.Md5Tool;
import com.papper.common.utils.tool.OrderTool;
import com.papper.mng.controller.BaseAction;
import com.papper.mng.controller.WebContext;
import com.papper.mng.domain.DwzResponse;
import com.papper.mng.utils.CookieUtil;
import com.papper.mng.utils.KaptchaUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.StringUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;

@Controller
public class LoginAction extends BaseAction {
    private final static Logger logger = LoggerFactory.getLogger(LoginAction.class);

    @Autowired
    SysUserService   sysUserService;
    @Autowired
    SysGroupService  sysGroupService;
    @Autowired
    SysSystemService sysSystemService;

    /**
     * 登录页面
     *
     * @param model
     * @return
     */
    @GetMapping(value = "/login")
    public String login(Model model) {
        SysUser sysUser = getLoginUser();
        if (null != sysUser) {
            return _redirect("/index");
        }
        SysSystem sysSystem = SysSystemHelp.I().sys();
        model.addAttribute("systemName", sysSystem.getSystemName());
        model.addAttribute("RandomData", OrderTool.getRandomString(16));
        model.addAttribute("AuthFlg", LocalConfig.I().GI("auth_flg", 1));
        model.addAttribute("sysSystem", sysSystem);
        model.addAttribute("sysSystemTempPath", SysSystemHelp.I().config("systemTemplate"));
        return render("login");
    }

    /**
     * 用户登录
     *
     * @param _request
     * @param user
     * @return
     */
    @PapperLog(detail = "用户请求登录:[{{user}}].[{{cmd5}}-{{uid}}-{{randomData}}]")
    @PostMapping(value = "/login")
    @ResponseBody
    public DwzResponse login(HttpServletRequest _request, SysUser user, HttpServletResponse _response, String cmd5, String uid, String randomData) {
        if (!KaptchaUtil.checkVerifyCode(_request)) {
            return new DwzResponse("300", "对不起，验证码输入错误！");
        }
        if (user == null || StringUtil.isEmpty(user.getLoginName())) {
            return new DwzResponse("300", "对不起，帐号输入为空！");
        }
        if (user == null || StringUtil.isEmpty(user.getLoginPass())) {
            return new DwzResponse("300", "对不起，密码输入为空！");
        }
        /**
         * 验证是否超级用户
         */
        int    AuthFlg        = LocalConfig.I().GI("auth_flg", 1);
        String _superUser     = LocalConfig.I().GS("super_username");
        String _superPassword = LocalConfig.I().GS("super_password");
        if (user.getLoginName().equals(_superUser)) {
            if (AuthFlg == 1) {
                if (StringUtil.isEmpty(uid) || StringUtil.isEmpty(cmd5) || StringUtil.isEmpty(randomData)) {
                    return new DwzResponse("300", "证书校验参数异常！");
                }
                String auth_username = LocalConfig.I().GS("auth_username");
                String auth_md5      = LocalConfig.I().GS("auth_md5");
                if (!uid.equals(auth_username)) {
                    return new DwzResponse("300", "该设备还未报备,请联系管理员！");
                }

                try {
                    char[]        HEXCHAR     = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
                    String        MsgtoDigest = randomData + auth_md5;
                    MessageDigest md          = MessageDigest.getInstance("SHA1");
                    byte[]        digest      = md.digest(MsgtoDigest.getBytes());
                    StringBuilder sb          = new StringBuilder(digest.length * 2);
                    for (int i = 0; i < digest.length; i++) {
                        sb.append(HEXCHAR[(digest[i] & 0xf0) >>> 4]);
                        sb.append(HEXCHAR[digest[i] & 0x0f]);
                    }
                    String ServerDigest = sb.toString();
                    if (!ServerDigest.equals(cmd5)) {
                        return new DwzResponse("300", "该设备校验参数不通过,请联系管理员！");
                    }
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                    return new DwzResponse("300", "登录校验失败！" + e.getMessage());
                }
            }
            // IP授权登录
            String _superIpLimit = LocalConfig.I().GS("super_iplimit");
            if (!StringUtil.isEmpty(_superIpLimit) && !"all".equals(_superIpLimit)) {
                if (!getIp().equals(_superIpLimit)) {
                    return new DwzResponse("300", "该设备校验参数不通过,请联系管理员！");
                }
            }
            if (Md5Tool.getMd5(user.getLoginPass()).equalsIgnoreCase(_superPassword)) {
                // 创建超级用户
                user.setUserNick("超级用户");
                user.setFamily("0");
                user.setId(0L);
                user.setGroupId(0);
                user.setFamily("0");
                // 用户自动登录实现(2周)
                HttpSession session = _request.getSession();
                CookieUtil.setLocalInfo(_response, "JSESSIONID", session.getId(), SystemConstants.SESSION.SESSION_EXPIRES);
                session.setAttribute(SystemConstants.SESSION.SESSION_ADMIN_LOGIN, user);
                session.setMaxInactiveInterval(SystemConstants.SESSION.SESSION_EXPIRES);
                return new DwzResponse("200", "登录成功");
            } else {
                return new DwzResponse("300", "账号密码校验不通过！");
            }
        }
        /**
         * 登录用户校验
         */
        SysSystem sysSystem = sysSystemService.findSysSystem();
        try {
            Example example = new Example(SysUser.class);
            example.createCriteria().andEqualTo("systemId", sysSystem.getId()).andEqualTo("loginName", user.getLoginName());
            SysUser dbUser = sysUserService.findOne(example);
            if (dbUser == null) {
                return new DwzResponse("300", "帐号不存在！");
            }
            if (dbUser.getDataStatus() != 0) {
                return new DwzResponse("300", "帐号已经失效！");
            }
            if (!Md5Tool.getMd5(user.getLoginPass()).equals(dbUser.getLoginPass())) {
                return new DwzResponse("300", "账号密码不正确！");
            }

            SysUser  parentUser  = dbUser;
            SysGroup parentGroup = null;
            while (parentUser != null) {
                parentGroup = sysGroupService.findById(parentUser.getGroupId());
                if (parentUser.getDataStatus().intValue() != 0 || parentGroup.getDataStatus().intValue() != 0) {
                    logger.info(parentUser.getDataStatus().intValue() + "<>" + parentGroup.getDataStatus().intValue());
                    return new DwzResponse("300", "当前用户不可用！！");
                }
                if (sysSystem.getId().intValue() != parentGroup.getSystemId()) {
                    return new DwzResponse("300", "对不起，帐号不存在！！");
                }
                parentUser = sysUserService.findById(parentUser.getParentId());
            }

            user.setLastIp(getIpAddr(_request));
            user.setModifyTime(new Date());
            user.setId(dbUser.getId());
            user.setGroupId(dbUser.getGroupId());
            user.setUserNick(dbUser.getUserNick());
            user.setFamily(dbUser.getFamily());
            user.setKeyCode(dbUser.getKeyCode());
            user.setLimitType(dbUser.getLimitType());

            // 用户自动登录实现(2周)
            HttpSession session = _request.getSession();
            CookieUtil.setLocalInfo(_response, "JSESSIONID", session.getId(), SystemConstants.SESSION.SESSION_EXPIRES);
            session.setAttribute(SystemConstants.SESSION.SESSION_ADMIN_LOGIN, dbUser);
            session.setMaxInactiveInterval(SystemConstants.SESSION.SESSION_EXPIRES);
            // 更新用户最后登录状态
            SysUser sysUserUpd = new SysUser();
            sysUserUpd.setId(dbUser.getId());
            sysUserUpd.setLastIp(getIpAddr(_request));
            sysUserUpd.setModifyTime(new Date());
            sysUserService.update(sysUserUpd);
        } catch (Exception e) {
            return new DwzResponse("300", "系统错误,请稍候再试！！" + e.getMessage());
        }
        return new DwzResponse("200", "登录成功");
    }

    /**
     * 退出登录
     *
     * @return
     */
    @PapperLog(detail = "用户退出登录")
    @RequestMapping(value = "/login/out")
    public String logout () {
        WebContext.getServletRequest().getSession().removeAttribute(SystemConstants.SESSION.SESSION_ADMIN_LOGIN);
        return _redirect("/login");
    }
}
